package com.springbooti18n.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 全局异常拦截器，拦截之后国际化处理
 * xufan
 * 2019/1/4
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value(value = "${spring.messages.basename}")
    private String basename ;
    @Resource
    ResourceBundleMessageSource  messageSource;
    /**
     * 验证异常
     * @param req
     * @param e
     * @return
     * @throws MethodArgumentNotValidException
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public DataResponse handleMethodArgumentNotValidException
    (HttpServletRequest req, HttpServletResponse res, MethodArgumentNotValidException e) throws MethodArgumentNotValidException {
        DataResponse r = new DataResponse();
        BindingResult bindingResult = e.getBindingResult();
        String errorMesssage = "Invalid Request:\n";
        Map<String,Object> resData = new HashMap();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMesssage += fieldError.getDefaultMessage() + "\n";
            resData.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        r.setStatus(res.getStatus());
        r.setStatus(HttpStatus.BAD_REQUEST);
        r.setMessage(errorMesssage);
        r.setData(resData);
        logger.info("MethodArgumentNotValidException",e);
        return r;
    }

    /**
     * 全局异常
     * @param req
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = I18nException.class)
    @ResponseBody
    public DataResponse handleException(
            HttpServletRequest req, HttpServletResponse res, I18nException e) throws Exception {

        System.out.println("异常拦截"+"---"+e.getMessage());
        String messageKey = e.getMessageKey();
        List list = e.getAddMessage();
        String message = "";
        messageSource.setBasenames(basename);
        if(list != null){
            message = messageSource.getMessage(messageKey,
                    e.getAddMessage().toArray(), LocaleContextHolder.getLocale());
        }else{
            message=messageSource.getMessage(messageKey,null
                    , LocaleContextHolder.getLocale());
        }

        DataResponse r = new DataResponse();
        r.setStatus(HttpStatus.BAD_REQUEST);
        r.setMessage(message);
//        res.setStatus(HttpStatus.BAD_REQUEST.value());
        logger.error(e.getMessage(),e);
        return r;
    }


//    @ExceptionHandler(value =BindException.class)
//    @ResponseBody
//    public DataResponse handleBindException(BindException e) throws BindException {
//        // ex.getFieldError():随机返回一个对象属性的异常信息。如果要一次性返回所有对象属性异常信息，则调用ex.getAllErrors()
//        FieldError fieldError = e.getFieldError();
//        StringBuilder sb = new StringBuilder();
//        sb.append(fieldError.getField()).append("=[").append(fieldError.getRejectedValue()).append("]")
//                .append(fieldError.getDefaultMessage());
//        // 生成返回结果
//        DataResponse r = new DataResponse();
//        r.setResCode("401");
//        r.setMsg(sb.toString());
//        logger.info("BindException", e);
//        return r;
//    }
}
